// Wrap code in an self-executing anonymous function and 
// pass jQuery into it so we can use the "$" shortcut without 
// causing potential conflicts with already existing functions.
(function($) {


 var Validation = function() {
        var rules = {  // Private object
                email : {
                    check: function(value) {
                        if(value) {
                            //return testPattern(value,"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])");
                            return testPatternEmail(value);
                        }
                        return true;
                    },
                msg : "EnZOOOOOOOOOOOMMMMMMMMMM."
                },

                confirm_email: {
                    check: function(main_field, confirm_field) {
                        return main_field === confirm_field;
                    },
                    msg : "sddddddddddddddddddddddddddddddddddatch."
                },
                
                required : {
                    check: function(value) {
                        value = $.trim(value);
                        if(value) {
                            return true;
                        }
                        else {
                            return false;
                        }
                    },
                    msg : "This fielZOOOOOOOOMMMMMMMMMM required."
                },

                required_dropdown : {
                        check: function(value) {
                            if(value !== "") {
                                return true;
                            }
                            else {
                                return false;
                            }
                        },
                        msg : "SZOOOOOMMMMMMMMMMMDropdown "   
                    }
                };

    var testPatternEmail =  function(value) {   // Private Method
        var regExp = /^[A-Za-z0-9._%+-]+@([A-Za-z0-9.-]+\.com|gmail\.com)$/;
        return regExp.test(value);
    };

    var testPattern = function(value, pattern) {   // Private Method
        var regExp = new RegExp(pattern,"");
        //console.log(regExp.test(value));
        return regExp.test(value);
    };

    return { // Public methods
        addRule : function(name, rule) {
            rules[name] = rule;
        },
        getRule : function(name) {
            return rules[name];
        }
    };

};


//A new instance of our object in the jQuery namespace.
$.Validation = new Validation();


//Generic form objects
//
// First the field object
var Field = function(field) {
    this.field = field;
    this.valid = false;
    this.attach("change");
};  

Field.prototype = {
    // Method used to attach different type of events to
    // the field object.
    attach : function(event) {

        var obj = this;
        if(event === "change") {
            obj.field.bind("change",function() {
                return obj.validate();
            });
        }
        if(event === "keyup") {
            obj.field.bind("keyup",function(e) {
                return obj.validate();
            });
        }
    },



    // Method that runs validation on a field
    validate : function() {
        // Create an internal reference to the Field object. 
        var obj = this,
        // The actual input, textarea in the object
        field = obj.field, 
        fieldErrors = {},
        errorClass = "errorlist",
        errorlist;



        // A field can have multiple values to the validation
        // attribute, seprated by spaces.
        types = field.attr("validation").split(" "), 
              container = field.parent(),
              errors = []; 

        // Give the flexibility of custom messages for the errors.

        if(field.data('errors')){
            fieldErrors = $.parseJSON(field.data('errors'));
        }


        // If there is an errorlist already present
        // remove it before performing additional validation
        field.parent().find('.a-alert-inline').remove();

        // Iterate over validation types
        for (var type in types) {

            // Get the rule from our Validation object.
            var rule = $.Validation.getRule(types[type]);

            if(types[type] === "confirm_email") {

                var match_field = '#'+field.attr('confirm_email_field');
               

                if(!rule.check(field.val(),$(match_field).val())) {

                    field.addClass("a-form-error");

                    var errorType = types[type];

                    // Allow the overridden msg to appear instead of the generic error msg for a perticular rule.
                    if(fieldErrors[errorType] != undefined){
                        errors.push(fieldErrors[errorType]);
                    } else {
                        errors.push(rule.msg);
                    }

                }

            } else {
                if(!rule.check(field.val())) {

                    field.addClass("a-form-error");

                    var errorType = types[type];

                    // Allow the overridden msg to appear instead of the generic error msg for a perticular rule.
                    if(fieldErrors[errorType] != undefined){
                        errors.push(fieldErrors[errorType]);
                    } else {
                        errors.push(rule.msg);
                    }

                }
            }


        }
        // If there is one ore more errors
        if(errors.length) {

            // Remove existing event handler
            obj.field.unbind("keyup")
            // Attach the keyup event to the field because now
            // we want to let the user know as soon as she has
            // corrected the error
            obj.attach("keyup");
            // console.log(errorlist.next('.a-tooltip-inner'));
            // Empty existing errors, if any.
            var errorMsgs = $('<div class="a-box a-alert-inline a-alert-inline-error"><div class="a-box-inner"> <i class="a-icon a-icon-alert"></i> <p></p> </div> </div>');
            
            for(error in errors) {
                errorMsgs.find('p').append(errors[error] + '<br/>');        
            }
            field.after(errorMsgs);
            obj.valid = false;
        } 
        // No errors
        else {
            field.removeClass("a-form-error");
            obj.valid = true;
        }
    }
};


var Form = function(form) {

    var fields = [];
    // Get all input elements in form
    for( var i=0; i < form[0].elements.length; i++) {
        var field = $(form[0].elements[i]);

        // We're only interested in fields with a validation attribute
        if(typeof field.attr('validation') !== "undefined") {
            fields.push(new Field(field));
        }
    }
    this.fields = fields;

    var that = this;
    var overrun = 0; // Just to avoid too many timeouts.

    form.keydown(function(){
        if(overrun === 0){
            overrun = 1
            setTimeout(function(){
                that.validate();
                overrun = 0;
            }, 2000);
        }
    });
}; 

Form.prototype = {
    validate : function() {
        for(var j=0; j < this.fields.length ; j++) {
            //console.log(this.fields[j]);
            this.fields[j].validate();
        }
    },
    isValid : function() {
        for(var k=0;  k < this.fields.length; k++) {
            if(!this.fields[k].valid) {
                // Focus the first field that contains
                // an error to let user fix it. 
                this.fields[k].field.focus();
                // As soon as one field is invalid
                // we can return false right away.
                return false;
            }
        }
        return true;
    },
};




$.extend($.fn, {
    validation : function() {
        window.validator = new Form($(this));
        $.data($(this)[0], 'validator', validator);
        $(this).bind("submit", function(e) {

        validator.validate();
            if(!validator.isValid()) {
                e.preventDefault();
            }
        });
    },
    validate : function() {
        var validator = $.data($(this)[0], 'validator');
        validator.validate();
        return validator.isValid();
    }
});



})(jQuery); 
// Again, we're passing jQuery into the function 
// so we can use $ without potential conflicts.
